﻿/*
<File>
	<Copyright>Copyright © 2007, Outcoder. All rights reserved.</Copyright>
	<License see="//License.txt"/>
	<Owner Name="Daniel Vaughan" Email="danielvaughan@outcoder.com"/>
	<CreationDate>2007/11/27 12:44</CreationDate>
	<LastSubmissionDate>$Date: $</LastSubmissionDate>
	<Version>$Revision: $</Version>
</File>
*/

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Security;

namespace Outcoder.Logging.Filters
{
	/// <summary>
	/// Restricts a log entry based on the log entries
	/// <see cref="ILogEntry.MachineName"/> value,
	/// as specified in the comma delimited <em>machines</em> attribute
	/// of the filter element.
	/// <seealso cref="Environment.MachineName"/>
	/// </summary>
	class MachineFilter : FilterBase
	{
//		bool trusted;

		readonly List<string> machines = new List<string>();

		/// <summary>
		/// Gets or sets a set of machine names to be used by an <see cref="IFilter"/>.
		/// </summary>
		/// <value>The users.</value>
		public IEnumerable<string> Machines
		{
			get
			{
				return machines;
			}
		}
			
		public MachineFilter()
		{
			Init += EnvironmentUserFilter_Init;
		}

		void EnvironmentUserFilter_Init(object sender, FilterInitEventArgs e)
		{
			ArgumentValidator.AssertNotNull(e, "e");
			ArgumentValidator.AssertNotNull(e.ConfigurationElement, "e.ConfigurationElement");

			/* Reset state. */
			machines.Clear();

			/* TODO: put in util.*/
			var machinesAttribute = e.ConfigurationElement.Attributes["Machines"];
			if (machinesAttribute == null)
			{
				throw new ClientLoggingException("Machines attribute does not exists."); /* TODO: Make localizable resource. */
			}
			try
			{
				string machinesValue = machinesAttribute.Value;
				var machineValues = machinesValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				machines.AddRange(machineValues);
			}
			catch (Exception ex)
			{
				throw new ClientLoggingException("Users attribute is invalid. Should be a comma seperated list of names.", ex); /* TODO: Make localizable resource. */
			}

			if (Action == FilterAction.Default)
			{
				Action = FilterAction.Allow;
			}
			if (Action != FilterAction.Allow && Action != FilterAction.Deny)
			{
				throw new ConfigurationErrorsException(InvalidActionMessage);
			}
		}

		public override bool IsValid(LogEntryOrigin origin, IClientInfo info)
		{
			string machineName = info.MachineName;

			foreach (string name in machines)
			{
				if (machineName != name)
				{
					continue;
				}

				if (Action == FilterAction.Deny)
				{
					return false;
				}

				if (Action == FilterAction.Allow)
				{
					return true;
				}
			}

			return Action != FilterAction.Allow;
		}
	}
}
